/**
 * @fileOverview    文件处理函数.
 * @author          shaozhe.ysz@alibabapictures.com
 * @since           2016.07.29
 */

const
    fs = require('fs'),
    path = require('path'),
    c = require('./c'),
    debug = require('./debug'),
    Cache = require('./cache'),
    config = require('../.picom'),
    request = require('request');

const
    MAP = config.map,
    PROXIES = config.proxies,
    CACHE_PATH = path.resolve(__dirname,'../cache'),
    ROOT_PATH = path.resolve(__dirname,'../../');

//获取文件
const getFile = function(origin){
    var [url,pro,host,path] = origin.match(/(https?:\/\/)([^\/]+)(\/.*)/);

    return new Promise((resolve,reject)=>{
        var key,isInMap=false;
        for(key in MAP){
            let reg = MAP[key];
            if(path.match(reg)){
                path = path.replace(reg,key);
                isInMap = true;
                break;
            }
        }

        if(isInMap){
            getLocal.bind(this)(path)
                .then(f=>resolve(f))
                .catch(err=>reject(err));
            return;
        }else{
            for(key in PROXIES){
                let target = PROXIES[key];
                if(url.match(key)){
                    url = url.replace(key,target);
                    getCache.bind(this)(url)
                        .then(f=>resolve(f))
                        .catch(err=>{
                            getRemote.bind(this)(url)
                                .then(f=>{
                                Cache.set(url,f);
                                this.log(c.green('Cache: ')+url);
                                resolve(f);
                            })
                            .catch(err=>reject(err));
                        })
                    return;
                }
            }
        }
        reject(new Error('nothing matched!'));
    })
}

const 
    //获取本地文件
    getLocal=function(path){
        return new Promise((resolve,reject)=>{
            fs.readFile(path,'utf8',(err,f)=>{
                if(err){
                    this.log(c.cyan('=> Local: ')+path+c.red(' ->Error!'));
                    reject(err);
                }else{
                    this.log(c.cyan('=> Local: ')+path+c.green(' ->Success!'));
                    resolve(f);
                }
            })
        })
    },
    getCache=function(url){
        return new Promise((resolve,reject)=>{
            Cache.get(url)
                .then(f=>{
                    this.log(c.cyan('=> Cache: ')+url+c.green(' ->Success!'));
                    resolve(f);
                })
                .catch(err=>{
                    reject(err)
                });
        })
    },
    getRemote=function(url){
        return new Promise((resolve,reject)=>{
            request(url,(err,res,body)=>{
                if(body!=''){
                    resolve(body);
                    this.log(c.cyan('=> Remote: ')+url+c.green(' ->Success!'));
                }else{
                    reject(err||null);
                    this.log(c.cyan('=> Remote: ')+url+c.red(' ->Error!'));
                }
            })
        })
    };

/* -----------------------------------------------
                   P u b l i c
-----------------------------------------------  */

const getFiles = function(pathArr){
    return new Promise((resolve,reject)=>{
        Promise.all(pathArr.map(p=>getFile.bind(this)(p)))
        .then((fileArr)=>{
            resolve(fileArr);
        })
        .catch(err=>reject(err));
    })
};

const getPaths = function(origin,host,protocal='http'){

    var toURL = (path)=>`${protocal}:\/\/${host}${path}`;
    return new Promise((resolve,reject)=>{

        if(origin.match(/\?\?/)){
            let [root,paths] = origin.split('??');
            if(paths){
                paths = paths.split(',');
                paths = paths.map(p=>toURL(root+p));
                resolve(paths);
            }else{
                resolve([toURL(root)])
            }
        }else{
            resolve([toURL(origin)]);
        }
    })
}

module.exports = {
    getPaths,getFiles
}